"""
用户服务测试示例
展示如何使用增强的测试框架进行服务层测试
"""

from typing import List
from unittest.mock import Mock, patch
from sqlalchemy.orm import Session

from app.services.user_service import UserService
from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate
from tests.services.enhanced_service_test import EnhancedServiceTest
from tests.factories.test_data_factory import (
    create_user_create_data,
    create_user_update_data
)


class TestUserService(EnhancedServiceTest):
    """用户服务测试类"""
    
    def setup_method(self):
        """测试前准备"""
        super().setup_method()
        
        # 创建用户服务实例
        self.user_service = UserService(self.mock_db)
    
    def test_create_user_success(self):
        """测试创建用户成功"""
        # 准备测试数据
        user_create = create_user_create_data()
        
        # 模拟数据库操作
        mock_user = Mock(spec=User)
        mock_user.id = 1
        mock_user.username = user_create.username
        mock_user.email = user_create.email
        mock_user.full_name = user_create.full_name
        
        self.setup_mock_add(return_value=mock_user)
        self.mock_db.query.return_value.filter.return_value.first.return_value = None
        
        # 执行测试
        result = self.user_service.create_user(user_create)
        
        # 验证结果
        self.assert_service_result(result, User, {
            "username": user_create.username,
            "email": user_create.email
        })
        
        # 验证数据库调用
        self.mock_db.add.assert_called_once()
        self.mock_db.commit.assert_called_once()
        self.mock_db.refresh.assert_called_once()
    
    def test_get_user_by_id_success(self):
        """测试根据ID获取用户成功"""
        # 模拟数据库查询
        mock_user = Mock(spec=User)
        mock_user.id = 1
        mock_user.username = "testuser"
        mock_user.email = "test@example.com"
        
        mock_query = Mock()
        mock_query.filter.return_value.first.return_value = mock_user
        self.mock_db.query.return_value = mock_query
        
        # 执行测试
        result = self.user_service.get_by_id(1)
        
        # 验证结果
        self.assert_service_result(result, User, {
            "id": 1,
            "username": "testuser"
        })
        
        # 验证数据库调用
        self.mock_db.query.assert_called_once_with(User)
        mock_query.filter.assert_called_once()
    
    def test_get_all_users_success(self):
        """测试获取所有用户成功"""
        # 模拟数据库查询
        mock_users = []
        for i in range(3):
            mock_user = Mock(spec=User)
            mock_user.id = i + 1
            mock_user.username = f"user{i+1}"
            mock_users.append(mock_user)
        
        mock_query = Mock()
        mock_query.offset.return_value.limit.return_value.all.return_value = mock_users
        self.mock_db.query.return_value = mock_query
        
        # 执行测试
        result = self.user_service.get_all(skip=0, limit=10)
        
        # 验证结果
        self.assert_service_list_result(result, 3, User)
        
        # 验证数据库调用
        self.mock_db.query.assert_called_once_with(User)
        mock_query.offset.assert_called_once_with(0)
        mock_query.limit.assert_called_once_with(10)
    
    def test_update_user_success(self):
        """测试更新用户成功"""
        # 模拟数据库查询
        mock_user = Mock(spec=User)
        mock_user.id = 1
        mock_user.username = "old_username"
        mock_user.email = "old@example.com"
        mock_user.full_name = "Old Name"
        
        mock_query = Mock()
        mock_query.filter.return_value.first.return_value = mock_user
        self.mock_db.query.return_value = mock_query
        
        # 准备更新数据
        user_update = create_user_update_data(full_name="New Name", phone="1234567890")
        
        # 执行测试
        result = self.user_service.update_user(1, user_update)
        
        # 验证结果
        self.assert_service_result(result, User, {
            "id": 1,
            "full_name": "New Name"
        })
        
        # 验证属性更新
        assert mock_user.full_name == "New Name"
        assert mock_user.phone == "1234567890"
        
        # 验证数据库调用
        self.mock_db.commit.assert_called_once()
        self.mock_db.refresh.assert_called_once()
    
    def test_delete_user_success(self):
        """测试删除用户成功"""
        # 模拟数据库查询
        mock_user = Mock(spec=User)
        mock_user.id = 1
        
        mock_query = Mock()
        mock_query.filter.return_value.first.return_value = mock_user
        self.mock_db.query.return_value = mock_query
        
        # 执行测试
        result = self.user_service.delete_user(1)
        
        # 验证结果
        assert result is True
        
        # 验证数据库调用
        self.mock_db.delete.assert_called_once_with(mock_user)
        self.mock_db.commit.assert_called_once()
    
    def test_calculate_profile_completion(self):
        """测试计算用户资料完整度"""
        # 创建模拟用户
        mock_user = Mock(spec=User)
        mock_user.email = "test@example.com"
        mock_user.phone = "1234567890"
        mock_user.full_name = "Test User"
        mock_user.avatar = "avatar.jpg"
        
        # 执行测试
        completion = self.user_service.calculate_profile_completion(mock_user)
        
        # 验证结果
        assert completion == 100  # 所有字段都已填写
        
        # 测试部分填写
        mock_user.phone = None
        mock_user.avatar = None
        completion = self.user_service.calculate_profile_completion(mock_user)
        assert completion == 50  # 一半字段已填写


if __name__ == "__main__":
    # 这里可以添加直接运行测试的代码
    pass